<template><div><h2 id="过滤器" tabindex="-1"><a class="header-anchor" href="#过滤器"><span>过滤器</span></a></h2>
<p>过滤器是 <a href="https://github.com/yiisoft/yii2/blob/master/docs/guide-zh-CN/structure-controllers.md#actions" target="_blank" rel="noopener noreferrer">控制器动作</a> 执行之前或之后执行的对象。例如，访问控制过滤器可在动作执行之前来控制特殊终端用户是否有权限执行动作，内容压缩过滤器可在动作执行之后发给终端用户之前压缩响应内容。</p>
<p>过滤器可包含预过滤（过滤逻辑在动作<em>之前</em>）或后过滤（过滤逻辑在动作<em>之后</em>），也可同时包含两者。</p>
<h2 id="使用过滤器" tabindex="-1"><a class="header-anchor" href="#使用过滤器"><span>使用过滤器</span></a></h2>
<p>过滤器本质上是一类特殊的 <a href="https://github.com/yiisoft/yii2/blob/master/docs/guide-zh-CN/concept-behaviors.md" target="_blank" rel="noopener noreferrer">行为</a>，所以使用过滤器和 <a href="https://github.com/yiisoft/yii2/blob/master/docs/guide-zh-CN/concept-behaviors.md#attaching-behaviors" target="_blank" rel="noopener noreferrer">使用行为</a> 一样。可以在控制器类中覆盖它的 [[yii\base\Controller::behaviors()]] 方法来声明过滤器，如下所示：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">behaviors</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'class'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'yii\filters\HttpCache'</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'only'</span> <span class="token operator">=></span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'index'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'view'</span><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'lastModified'</span> <span class="token operator">=></span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$action</span><span class="token punctuation">,</span> <span class="token variable">$params</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">                <span class="token variable">$q</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name class-name-fully-qualified"><span class="token punctuation">\</span>yii<span class="token punctuation">\</span>db<span class="token punctuation">\</span>Query</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">                <span class="token keyword">return</span> <span class="token variable">$q</span><span class="token operator">-></span><span class="token function">from</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'user'</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">max</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'updated_at'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">            <span class="token punctuation">}</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>控制器类的过滤器默认应用到该类的 <em>所有</em> 动作，你可以配置 [[yii\base\ActionFilter::only]] 属性明确指定控制器应用到哪些动作。在上述例子中，<code v-pre>HttpCache</code> 过滤器只应用到 <code v-pre>index</code> 和 <code v-pre>view</code> 动作。也可以配置 [[yii\base\ActionFilter::except]] 属性使一些动作不执行过滤器。</p>
<p>除了控制器外，可在 <a href="https://github.com/yiisoft/yii2/blob/master/docs/guide-zh-CN/structure-modules.md" target="_blank" rel="noopener noreferrer">模块</a> 或 <a href="https://github.com/yiisoft/yii2/blob/master/docs/guide-zh-CN/structure-applications.md" target="_blank" rel="noopener noreferrer">应用主体</a> 中申明过滤器。申明之后，过滤器会应用到所属该模块或应用主体的 <em>所有</em> 控制器动作，除非像上述一样配置过滤器的 [[yii\base\ActionFilter::only]] 和 [[yii\base\ActionFilter::except]] 属性。</p>
<blockquote>
<p>Note: 在模块或应用主体中申明过滤器，在[[yii\base\ActionFilter::only]] 和 [[yii\base\ActionFilter::except]] 属性中使用 <a href="https://github.com/yiisoft/yii2/blob/master/docs/guide-zh-CN/structure-controllers.md#routes" target="_blank" rel="noopener noreferrer">路由</a> 代替动作 ID，因为在模块或应用主体中只用动作ID并不能唯一指定到具体动作。</p>
</blockquote>
<h2 id="多过滤器" tabindex="-1"><a class="header-anchor" href="#多过滤器"><span>多过滤器</span></a></h2>
<p>当一个动作有多个过滤器时，根据以下规则先后执行：</p>
<ul>
<li>预过滤
<ul>
<li>按顺序执行应用主体中 <code v-pre>behaviors()</code> 列出的过滤器。</li>
<li>按顺序执行模块中 <code v-pre>behaviors()</code> 列出的过滤器。</li>
<li>按顺序执行控制器中 <code v-pre>behaviors()</code> 列出的过滤器。</li>
<li>如果任意过滤器终止动作执行，后面的过滤器（包括预过滤和后过滤）不再执行。</li>
</ul>
</li>
<li>成功通过预过滤后执行动作。</li>
<li>后过滤
<ul>
<li>倒序执行控制器中 <code v-pre>behaviors()</code> 列出的过滤器。</li>
<li>倒序执行模块中 <code v-pre>behaviors()</code> 列出的过滤器。</li>
<li>倒序执行应用主体中 <code v-pre>behaviors()</code> 列出的过滤器。</li>
</ul>
</li>
</ul>
<h2 id="创建过滤器" tabindex="-1"><a class="header-anchor" href="#创建过滤器"><span>创建过滤器</span></a></h2>
<p>继承 <code v-pre>yii\base\ActionFilter</code> 类并覆盖 [[yii\base\ActionFilter::beforeAction()]] 或 [[yii\base\ActionFilter::afterAction()]] 方法来创建动作的过滤器，前者在动作执行之前执行，后者在动作执行之后执行。[[yii\base\ActionFilter::beforeAction()]] 返回值决定动作是否应该执行，如果为 <code v-pre>false</code>，之后的过滤器和动作不会继续执行。</p>
<p>下面的例子申明一个记录动作执行时间日志的过滤器。</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">namespace</span> <span class="token package">app<span class="token punctuation">\</span>components</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Yii</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">yii<span class="token punctuation">\</span>base<span class="token punctuation">\</span>ActionFilter</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">ActionTimeFilter</span> <span class="token keyword">extends</span> <span class="token class-name">ActionFilter</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">private</span> <span class="token variable">$_startTime</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">beforeAction</span><span class="token punctuation">(</span><span class="token variable">$action</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">_startTime</span> <span class="token operator">=</span> <span class="token function">microtime</span><span class="token punctuation">(</span><span class="token constant boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">        <span class="token keyword">return</span> <span class="token keyword static-context">parent</span><span class="token operator">::</span><span class="token function">beforeAction</span><span class="token punctuation">(</span><span class="token variable">$action</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">afterAction</span><span class="token punctuation">(</span><span class="token variable">$action</span><span class="token punctuation">,</span> <span class="token variable">$result</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token variable">$time</span> <span class="token operator">=</span> <span class="token function">microtime</span><span class="token punctuation">(</span><span class="token constant boolean">true</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">_startTime</span><span class="token punctuation">;</span></span>
<span class="line">        <span class="token class-name static-context">Yii</span><span class="token operator">::</span><span class="token function">debug</span><span class="token punctuation">(</span><span class="token string double-quoted-string">"Action '<span class="token interpolation"><span class="token punctuation">{</span><span class="token variable">$action</span><span class="token operator">-></span><span class="token property">uniqueId</span><span class="token punctuation">}</span></span>' spent <span class="token interpolation"><span class="token variable">$time</span></span> second."</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">        <span class="token keyword">return</span> <span class="token keyword static-context">parent</span><span class="token operator">::</span><span class="token function">afterAction</span><span class="token punctuation">(</span><span class="token variable">$action</span><span class="token punctuation">,</span> <span class="token variable">$result</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="核心过滤器" tabindex="-1"><a class="header-anchor" href="#核心过滤器"><span>核心过滤器</span></a></h2>
<p>Yii 提供了一组常用过滤器，在 <code v-pre>yii\filters</code> 命名空间下，接下来我们简要介绍这些过滤器。</p>
<h3 id="访问控制过滤器" tabindex="-1"><a class="header-anchor" href="#访问控制过滤器"><span>访问控制过滤器</span></a></h3>
<p><code v-pre>yii\filters\AccessControl</code> 提供基于 [[yii\filters\AccessControl::rules]] 规则的访问控制。特别是在动作执行之前，访问控制会检测所有规则并找到第一个符合上下文的变量（比如用户 IP 地址、登录状态等）的规则，来决定允许还是拒绝请求动作的执行，如果没有规则符合，访问就会被拒绝。</p>
<p>如下示例表示表示允许已认证用户访问 <code v-pre>create</code> 和 <code v-pre>update</code> 动作，拒绝其他用户访问这两个动作。</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">yii<span class="token punctuation">\</span>filters<span class="token punctuation">\</span>AccessControl</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">behaviors</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'access'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'class'</span> <span class="token operator">=></span> <span class="token class-name static-context">AccessControl</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'only'</span> <span class="token operator">=></span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'create'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'update'</span><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'rules'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">                <span class="token comment">// 允许认证用户</span></span>
<span class="line">                <span class="token punctuation">[</span></span>
<span class="line">                    <span class="token string single-quoted-string">'allow'</span> <span class="token operator">=></span> <span class="token constant boolean">true</span><span class="token punctuation">,</span></span>
<span class="line">                    <span class="token string single-quoted-string">'roles'</span> <span class="token operator">=></span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'@'</span><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token comment">// 默认禁止其他用户</span></span>
<span class="line">            <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>更多关于访问控制的详情请参阅 <a href="https://github.com/yiisoft/yii2/blob/master/docs/guide-zh-CN/security-authorization.md" target="_blank" rel="noopener noreferrer">授权</a> 一节。</p>
<h3 id="认证方法过滤器" tabindex="-1"><a class="header-anchor" href="#认证方法过滤器"><span>认证方法过滤器</span></a></h3>
<p>认证方法过滤器通过 <a href="http://en.wikipedia.org/wiki/Basic_access_authentication" target="_blank" rel="noopener noreferrer">HTTP 基础认证</a> 或 <a href="http://oauth.net/2/" target="_blank" rel="noopener noreferrer">OAuth 2</a> 来认证一个用户，认证方法过滤器类在 <code v-pre>yii\filters\auth</code> 命名空间下。</p>
<p>如下示例表示可使用 <code v-pre>yii\filters\auth\HttpBasicAuth</code> 来认证一个用户，它使用基于 HTTP 基础认证方法的令牌。注意为了可运行，<code v-pre>yii\web\User::identityClass</code> 用户身份类必须实现 [[yii\web\IdentityInterface::findIdentityByAccessToken()]] 方法。</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">yii<span class="token punctuation">\</span>filters<span class="token punctuation">\</span>auth<span class="token punctuation">\</span>HttpBasicAuth</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">behaviors</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'basicAuth'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'class'</span> <span class="token operator">=></span> <span class="token class-name static-context">HttpBasicAuth</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>认证方法过滤器通常在实现 RESTful API 中使用，更多关于访问控制的详情请参阅 RESTful <a href="https://github.com/yiisoft/yii2/blob/master/docs/guide-zh-CN/rest-authentication.md" target="_blank" rel="noopener noreferrer">认证</a> 一节。</p>
<h3 id="内容转让过滤器" tabindex="-1"><a class="header-anchor" href="#内容转让过滤器"><span>内容转让过滤器</span></a></h3>
<p><code v-pre>yii\filters\ContentNegotiator</code> 支持响应内容格式处理和语言处理。通过检查 <code v-pre>GET</code> 参数和 <code v-pre>Accept</code> HTTP 头部来决定响应内容格式和语言。</p>
<p>在控制器或模块中使用 ContentNegotiator 作为动作过滤器，并支持 JSON 和 XML 响应格式和英语（美国）和德语，如下示例：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">yii<span class="token punctuation">\</span>filters<span class="token punctuation">\</span>ContentNegotiator</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">yii<span class="token punctuation">\</span>web<span class="token punctuation">\</span>Response</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">behaviors</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'class'</span> <span class="token operator">=></span> <span class="token class-name static-context">ContentNegotiator</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token comment">// 在一个控制器里</span></span>
<span class="line">            <span class="token string single-quoted-string">'only'</span> <span class="token operator">=></span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'view'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'index'</span><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token comment">// 如果是在模块中，则使用以下 id 代表用户动作</span></span>
<span class="line">            <span class="token comment">// 'only' => ['user/view', 'user/index']</span></span>
<span class="line">            <span class="token string single-quoted-string">'formats'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">                <span class="token string single-quoted-string">'application/json'</span> <span class="token operator">=></span> <span class="token class-name static-context">Response</span><span class="token operator">::</span><span class="token constant">FORMAT_JSON</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token string single-quoted-string">'application/xml'</span> <span class="token operator">=></span> <span class="token class-name static-context">Response</span><span class="token operator">::</span><span class="token constant">FORMAT_XML</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'languages'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">                <span class="token string single-quoted-string">'en-US'</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token string single-quoted-string">'de'</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>在 <a href="https://github.com/yiisoft/yii2/blob/master/docs/guide-zh-CN/structure-applications.md#application-lifecycle" target="_blank" rel="noopener noreferrer">应用主体生命周期</a> 过程中检测响应格式和语言简单很多，因此 ContentNegotiator 设计可被 <a href="https://github.com/yiisoft/yii2/blob/master/docs/guide-zh-CN/structure-applications.md#bootstrap" target="_blank" rel="noopener noreferrer">引导启动组件</a> 调用的过滤器。如下例所示可以将它配置在 <a href="https://github.com/yiisoft/yii2/blob/master/docs/guide-zh-CN/structure-applications.md#application-configurations" target="_blank" rel="noopener noreferrer">应用主体配置</a>。</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">yii<span class="token punctuation">\</span>filters<span class="token punctuation">\</span>ContentNegotiator</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">yii<span class="token punctuation">\</span>web<span class="token punctuation">\</span>Response</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token punctuation">[</span></span>
<span class="line">    <span class="token string single-quoted-string">'bootstrap'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'class'</span> <span class="token operator">=></span> <span class="token class-name static-context">ContentNegotiator</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'formats'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">                <span class="token string single-quoted-string">'application/json'</span> <span class="token operator">=></span> <span class="token class-name static-context">Response</span><span class="token operator">::</span><span class="token constant">FORMAT_JSON</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token string single-quoted-string">'application/xml'</span> <span class="token operator">=></span> <span class="token class-name static-context">Response</span><span class="token operator">::</span><span class="token constant">FORMAT_XML</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'languages'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">                <span class="token string single-quoted-string">'en-US'</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token string single-quoted-string">'de'</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><blockquote>
<p>Info: 如果请求中没有检测到内容格式和语言，使用 <code v-pre>formats</code> 和 <code v-pre>languages</code> 首个配置项。</p>
</blockquote>
<h3 id="http-缓存过滤器" tabindex="-1"><a class="header-anchor" href="#http-缓存过滤器"><span>Http 缓存过滤器</span></a></h3>
<p><code v-pre>yii\filters\HttpCache</code> 利用 <code v-pre>Last-Modified</code> 和 <code v-pre>Etag</code> HTTP 头实现客户端缓存。例如：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">yii<span class="token punctuation">\</span>filters<span class="token punctuation">\</span>HttpCache</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">behaviors</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'class'</span> <span class="token operator">=></span> <span class="token class-name static-context">HttpCache</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'only'</span> <span class="token operator">=></span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'index'</span><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'lastModified'</span> <span class="token operator">=></span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$action</span><span class="token punctuation">,</span> <span class="token variable">$params</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">                <span class="token variable">$q</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name class-name-fully-qualified"><span class="token punctuation">\</span>yii<span class="token punctuation">\</span>db<span class="token punctuation">\</span>Query</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">                <span class="token keyword">return</span> <span class="token variable">$q</span><span class="token operator">-></span><span class="token function">from</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'user'</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">max</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'updated_at'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">            <span class="token punctuation">}</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token comment">// 生成 响应中的“ETag”报头字段 种子字符串的PHP回调函数</span></span>
<span class="line">            <span class="token comment">//'etagSeed' => function ($action, $params) {</span></span>
<span class="line">            <span class="token comment">//    return // 构造 ETag seed</span></span>
<span class="line">            <span class="token comment">//}</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>更多关于使用它的详情，请参阅 <a href="https://github.com/yiisoft/yii2/blob/master/docs/guide-zh-CN/caching-http.md" target="_blank" rel="noopener noreferrer">HTTP 缓存</a> 一节。</p>
<h3 id="页面缓存过滤器" tabindex="-1"><a class="header-anchor" href="#页面缓存过滤器"><span>页面缓存过滤器</span></a></h3>
<p><code v-pre>yii\filters\PageCache</code> 实现服务器端整个页面的缓存。如下示例所示，PageCache 应用在 <code v-pre>index</code> 动作，缓存整个页面 60 秒或 <code v-pre>post</code> 表的记录数发生变化。它也会根据不同应用语言保存不同的页面版本。</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">yii<span class="token punctuation">\</span>filters<span class="token punctuation">\</span>PageCache</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">yii<span class="token punctuation">\</span>caching<span class="token punctuation">\</span>DbDependency</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">behaviors</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'pageCache'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'class'</span> <span class="token operator">=></span> <span class="token class-name static-context">PageCache</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'only'</span> <span class="token operator">=></span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'index'</span><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'duration'</span> <span class="token operator">=></span> <span class="token number">60</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'dependency'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">                <span class="token string single-quoted-string">'class'</span> <span class="token operator">=></span> <span class="token class-name static-context">DbDependency</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token string single-quoted-string">'sql'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'SELECT COUNT(*) FROM post'</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'variations'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">                <span class="token class-name class-name-fully-qualified static-context"><span class="token punctuation">\</span>Yii</span><span class="token operator">::</span><span class="token variable">$app</span><span class="token operator">-></span><span class="token property">language</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token punctuation">]</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>更多关于使用它的详情，请参阅 <a href="https://github.com/yiisoft/yii2/blob/master/docs/guide-zh-CN/caching-page.md" target="_blank" rel="noopener noreferrer">页面缓存</a> 一节。</p>
<h3 id="限流过滤器" tabindex="-1"><a class="header-anchor" href="#限流过滤器"><span>限流过滤器</span></a></h3>
<p><code v-pre>yii\filters\RateLimiter</code> 根据 <a href="https://baike.baidu.com/item/%E6%BC%8F%E6%A1%B6%E7%AE%97%E6%B3%95" target="_blank" rel="noopener noreferrer">漏桶算法</a> 来实现一个速率限制算法。你可以使用 RateLimiter，将它作为一个行为，附加到控制器或模块，如下所示：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">behaviors</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'rateLimiter'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'class'</span> <span class="token operator">=></span> <span class="token class-name class-name-fully-qualified static-context"><span class="token punctuation">\</span>yii<span class="token punctuation">\</span>filters<span class="token punctuation">\</span>RateLimiter</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>当用户超过速率限制时，RateLimiter 将抛出一个 [[TooManyRequestsHttpException]] 异常。</p>
<blockquote>
<p>Note：如果 <code v-pre>user</code> 组件的 <code v-pre>identityClass</code> 没有设置（相当于未登录授权的游客）或者没有实现 <code v-pre>yii\filters\RateLimitInterface</code>，RateLimiter 将不生效。</p>
</blockquote>
<p>速率限制，主要用在实现 RESTful APIs，就像老生常谈的接口限流，更多关于该过滤器详情请参阅 <a href="https://github.com/yiisoft/yii2/blob/master/docs/guide-zh-CN/rest-rate-limiting.md" target="_blank" rel="noopener noreferrer">速率限制</a> 一节。</p>
<h3 id="http-请求方法过滤器" tabindex="-1"><a class="header-anchor" href="#http-请求方法过滤器"><span>HTTP 请求方法过滤器</span></a></h3>
<p><code v-pre>yii\filters\VerbFilter</code> 检查请求动作的 HTTP 请求方式是否允许执行，如果不允许，会抛出 HTTP 405异常。如下示例，VerbFilter 指定 CRUD 动作所允许的请求方式。</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">yii<span class="token punctuation">\</span>filters<span class="token punctuation">\</span>VerbFilter</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">behaviors</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'verbs'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'class'</span> <span class="token operator">=></span> <span class="token class-name static-context">VerbFilter</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'actions'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">                <span class="token string single-quoted-string">'index'</span>  <span class="token operator">=></span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'get'</span><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token string single-quoted-string">'view'</span>   <span class="token operator">=></span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'get'</span><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token string single-quoted-string">'create'</span> <span class="token operator">=></span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'get'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'post'</span><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token string single-quoted-string">'update'</span> <span class="token operator">=></span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'get'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'put'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'post'</span><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token string single-quoted-string">'delete'</span> <span class="token operator">=></span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'post'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'delete'</span><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="cors-过滤器" tabindex="-1"><a class="header-anchor" href="#cors-过滤器"><span>CORS 过滤器</span></a></h3>
<p><a href="https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS" target="_blank" rel="noopener noreferrer">CORS（跨域资源共享）</a> 机制允许一个网页的许多资源（例如字体、JavaScript等）可以通过其他域名访问获取。特别是 JavaScript 的 AJAX 调用，可使用 XMLHttpRequest 机制，由于同源安全策略该跨域请求会被网页浏览器禁止。CORS 定义浏览器和服务器交互时哪些跨域请求允许和禁止。</p>
<p><code v-pre>yii\filters\Cors</code> CORS 过滤器应在 <strong>授权认证过滤器</strong> 之前定义，以保证 CORS 头部被发送。</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">yii<span class="token punctuation">\</span>filters<span class="token punctuation">\</span>Cors</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">yii<span class="token punctuation">\</span>helpers<span class="token punctuation">\</span>ArrayHelper</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">behaviors</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token class-name static-context">ArrayHelper</span><span class="token operator">::</span><span class="token function">merge</span><span class="token punctuation">(</span><span class="token punctuation">[</span></span>
<span class="line">        <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'class'</span> <span class="token operator">=></span> <span class="token class-name static-context">Cors</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token keyword static-context">parent</span><span class="token operator">::</span><span class="token function">behaviors</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>如果要将 CORS 过滤器添加到你的 API 中的 [[yii\rest\ActiveController]] 类，还要检查 <a href="https://github.com/yiisoft/yii2/blob/master/docs/guide-zh-CN/rest-controllers.md#cors" target="_blank" rel="noopener noreferrer">REST Controllers</a> 中的部分。</p>
<p>CROS 过滤器可以通过 [[yii\filters\Cors::$cors]] 属性进行调整。</p>
<ul>
<li><code v-pre>cors['Origin']</code>：定义允许来源的数组，可为 <code v-pre>['*']</code>（任何用户）或 <code v-pre>['http://www.myserver.net', 'http://www.myotherserver.com']</code>。 默认为 <code v-pre>['*']</code>。</li>
<li><code v-pre>cors['Access-Control-Request-Method']</code>：允许动作数组如 <code v-pre>['GET', 'OPTIONS', 'HEAD']</code>。默认为 <code v-pre>['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS']</code>。</li>
<li><code v-pre>cors['Access-Control-Request-Headers']</code>：允许请求头部数组，可为 <code v-pre>['*']</code> 所有类型头部 或 <code v-pre>['X-Request-With']</code> 指定类型头部。默认为 <code v-pre>['*']</code>。</li>
<li><code v-pre>cors['Access-Control-Allow-Credentials']</code>：定义当前请求是否使用证书，可为 <code v-pre>true</code>，<code v-pre>false</code> 或 <code v-pre>null</code>（不设置）。默认为 <code v-pre>null</code>。</li>
<li><code v-pre>cors['Access-Control-Max-Age']</code>: 定义请求的有效时间，默认为 <code v-pre>86400</code>。</li>
</ul>
<p>详细示例，如下：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">yii<span class="token punctuation">\</span>filters<span class="token punctuation">\</span>Cors</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">yii<span class="token punctuation">\</span>helpers<span class="token punctuation">\</span>ArrayHelper</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">behaviors</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token class-name static-context">ArrayHelper</span><span class="token operator">::</span><span class="token function">merge</span><span class="token punctuation">(</span><span class="token punctuation">[</span></span>
<span class="line">        <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'class'</span> <span class="token operator">=></span> <span class="token class-name static-context">Cors</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'cors'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">                <span class="token comment">// 允许来源</span></span>
<span class="line">                <span class="token string single-quoted-string">'Origin'</span> <span class="token operator">=></span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'http://www.myserver.com'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'https://www.myserver.com'</span><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token comment">// 只允许 POST 和 PUT 方法</span></span>
<span class="line">                <span class="token string single-quoted-string">'Access-Control-Request-Method'</span> <span class="token operator">=></span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'POST'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'PUT'</span><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token comment">// 允许请求头部 'X-Wsse'</span></span>
<span class="line">                <span class="token string single-quoted-string">'Access-Control-Request-Headers'</span> <span class="token operator">=></span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'X-Wsse'</span><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token comment">// 允许使用证书 (cookies, authorization headers等) 向浏览器公开</span></span>
<span class="line">                <span class="token string single-quoted-string">'Access-Control-Allow-Credentials'</span> <span class="token operator">=></span> <span class="token constant boolean">true</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token comment">// Allow OPTIONS caching</span></span>
<span class="line">                <span class="token string single-quoted-string">'Access-Control-Max-Age'</span> <span class="token operator">=></span> <span class="token number">3600</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token comment">// 允许 X-Pagination-Current-Page 头文件暴露给浏览器</span></span>
<span class="line">                <span class="token string single-quoted-string">'Access-Control-Expose-Headers'</span> <span class="token operator">=></span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'X-Pagination-Current-Page'</span><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token keyword static-context">parent</span><span class="token operator">::</span><span class="token function">behaviors</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>可以覆盖默认参数为每个动作调整 CORS 头部。例如，为 <code v-pre>login</code> 动作增加 <code v-pre>Access-Control-Allow-Credentials</code> 参数如下所示：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">yii<span class="token punctuation">\</span>filters<span class="token punctuation">\</span>Cors</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">yii<span class="token punctuation">\</span>helpers<span class="token punctuation">\</span>ArrayHelper</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">behaviors</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token class-name static-context">ArrayHelper</span><span class="token operator">::</span><span class="token function">merge</span><span class="token punctuation">(</span><span class="token punctuation">[</span></span>
<span class="line">        <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'class'</span> <span class="token operator">=></span> <span class="token class-name static-context">Cors</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'cors'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">                <span class="token string single-quoted-string">'Origin'</span> <span class="token operator">=></span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'http://www.myserver.net'</span><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token string single-quoted-string">'Access-Control-Request-Method'</span> <span class="token operator">=></span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'GET'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'HEAD'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'OPTIONS'</span><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'actions'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">                <span class="token string single-quoted-string">'login'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">                    <span class="token string single-quoted-string">'Access-Control-Allow-Credentials'</span> <span class="token operator">=></span> <span class="token constant boolean">true</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token punctuation">]</span></span>
<span class="line">            <span class="token punctuation">]</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token keyword static-context">parent</span><span class="token operator">::</span><span class="token function">behaviors</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="host-过滤器" tabindex="-1"><a class="header-anchor" href="#host-过滤器"><span>HOST 过滤器</span></a></h3>
<p>Yii 从 2.0.11 版本起，提供 <code v-pre>yii\filters\HostControl</code> 对请求的主机名提供简单的控制。这个过滤器，提供了针对 [“主机头”攻击] 的保护，且只允许对指定的主机名执行操作。</p>
<p>可以在应用主体配置，示例如下：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">return</span> <span class="token punctuation">[</span></span>
<span class="line">     <span class="token string single-quoted-string">'as hostControl'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">         <span class="token string single-quoted-string">'class'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'yii\filters\HostControl'</span><span class="token punctuation">,</span></span>
<span class="line">         <span class="token string single-quoted-string">'allowedHosts'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">             <span class="token string single-quoted-string">'example.com'</span><span class="token punctuation">,</span></span>
<span class="line">             <span class="token string single-quoted-string">'*.example.com'</span><span class="token punctuation">,</span></span>
<span class="line">         <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">     <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">     <span class="token comment">// ...</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>也可以在控制器中使用，具体如下：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">yii<span class="token punctuation">\</span>web<span class="token punctuation">\</span>Controller</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">yii<span class="token punctuation">\</span>filters<span class="token punctuation">\</span>HostControl</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">SiteController</span> <span class="token keyword">extends</span> <span class="token class-name">Controller</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">behaviors</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token keyword">return</span> <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'hostControl'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">                <span class="token string single-quoted-string">'class'</span> <span class="token operator">=></span> <span class="token class-name static-context">HostControl</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token string single-quoted-string">'allowedHosts'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">                    <span class="token string single-quoted-string">'example.com'</span><span class="token punctuation">,</span></span>
<span class="line">                    <span class="token string single-quoted-string">'*.example.com'</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"></span>
<span class="line">    <span class="token comment">// ...</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><blockquote>
<p>Note：最佳限制允许主机名的方法是，使用 web 服务器的“虚拟主机”配置。只有在此配置不可用或受到损害时，才应使用此筛选器。</p>
</blockquote>
<h3 id="ajax-过滤器" tabindex="-1"><a class="header-anchor" href="#ajax-过滤器"><span>AJAX 过滤器</span></a></h3>
<p>Yii 从 2.0.13 版本起，提供 <code v-pre>yii\filters\AjaxFilter</code>，允许仅对 ajax 请求限制访问。示例如下：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">behaviors</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'class'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'yii\filters\AjaxFilter'</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'only'</span> <span class="token operator">=></span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'index'</span><span class="token punctuation">]</span>，</span>
<span class="line">            <span class="token comment">//'errorMessage' = 'Request must be XMLHttpRequest.'</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><blockquote>
<p>💖喜欢本文档的，欢迎点赞、收藏、留言或转发，谢谢支持！<br>
作者邮箱：zhuzixian520@126.com，github地址：<a href="https://github.com/zhuzixian520" target="_blank" rel="noopener noreferrer">github.com/zhuzixian520</a></p>
</blockquote>
</div></template>


